//--------------------------------------------------------------
//
// Qizhi Zhang 
// ezhung@gmail.com
// http://www.moorwind.com
//
//--------------------------------------------------------------
package reader.dao
{
	import __AS3__.vec.Vector;
	
	import flash.data.SQLConnection;
	import flash.data.SQLResult;
	import flash.utils.setTimeout;
	
	import reader.model.vo.BlogLabelVO;
	import reader.model.vo.BlogSourceVO;
	import reader.model.vo.UserVO;

	public class BlogSourceDAO extends BaseDAO implements IBlogSourceDAO
	{
		//////////////////////////////////////////////////////////////////////////////
		//SQLStatement queries
		
		private static const INSERT_BLOG_SOURCE:String = "INSERT INTO blogSource (blogName, blogLink, blogRSS, labelId, userId, creatDate, lastPubDate) VALUES(:blogName, :blogLink, :blogRSS, :labelId, :userId, :creatDate, :lastPubDate)";
		private static const UPDATE_BLOG_SOURCE:String = "UPDATE blogSource SET blogName=:blogName, lastPubDate=:lastPubDate, lastPubTime=:lastPubTime,totalBlogs=:totalBlogs, newBlogs=:newBlogs, labelId=:labelId WHERE blogSourceId=:blogSourceId";
		private static const UPDATE_BLOG_SOURCE_LABEL:String = "UPDATE blogSource SET labelId=:labelId WHERE blogSourceId=:blogSourceId";
		private static const UPDATE_BLOG_SOURCE_RESET:String = "UPDATE blogSource SET labelId=-1 WHERE labelId=:labelId";
		private static const DELETE_BLOG_SOURCE:String = "DELETE FROM blogSource WHERE blogSourceId=:blogSourceId";
		private static const DELETE_BLOG_SOURCE_BY_USER:String = "DELETE FROM blogSource WHERE userId=:userId";
		private static const SELECT_BLOG_SOURCE:String = "SELECT blogSourceId, blogLink, blogName, blogRSS, labelId, lastPubDate, newBlogs, totalBlogs FROM blogSource WHERE blogSourceId=:blogSourceId";
		private static const SELECT_ALL_BLOG_SOURCE:String = "SELECT blogSourceId, blogLink, blogName, blogRSS, labelId, lastPubDate, newBlogs, totalBlogs FROM blogSource WHERE userId=:userId";
		private static const SELECT_COUNT:String = "SELECT COUNT(blogSourceId) FROM blogSource WHERE userId=:userId";
		
		//////////////////////////////////////////////////////////////////////////////
		//constructor
		public function BlogSourceDAO(connection:SQLConnection)
		{
			super(connection);
		}
		
		//////////////////////////////////////////////////////////////////////////////
		//methods
		
		//----------------------------------------------------------------------------
		//
		// INSERT
		//
		//----------------------------------------------------------------------------
		
		public function insertBlogSource(blogSource:BlogSourceVO, user:UserVO):int
		{
			var sqlResult:SQLResult = execute(INSERT_BLOG_SOURCE, {blogName: blogSource.blogName, blogLink: blogSource.blogLink, blogRSS: blogSource.blogRSS, labelId: blogSource.labelId, userId: user.userId, creatDate: new Date(), lastPubDate:blogSource.lastPubDate});
            return int(sqlResult.lastInsertRowID);
		}
		
		public function insertBlogsourceList(list:Vector.<BlogSourceVO>, user:UserVO):void
		{
			this.connection.begin();
			for each(var blogSource:BlogSourceVO in list)
			{
				executeTransaction(INSERT_BLOG_SOURCE, {blogName: blogSource.blogName, blogLink: blogSource.blogLink, blogRSS: blogSource.blogRSS, labelId: blogSource.labelId, userId: user.userId, creatDate: new Date(), lastPubDate:blogSource.lastPubDate});
			}
			try
			{
				if(!this.connection.inTransaction)
				{
					this.connection.commit();
				}
				else
				{
					setTimeout(callLaterCommit, delayCommitInterval);
				}	
			}
			catch(e:Error)
			{
				trace(e);
			}
		}
		
		//----------------------------------------------------------------------------
		//
		// UPDATE
		//
		//----------------------------------------------------------------------------
		
		public function updateBlogSource(blogSource:BlogSourceVO):Boolean
		{
			var obj:Object = {};			
			obj.blogName = blogSource.blogName;
			obj.lastPubDate = blogSource.lastPubDate;
			obj.lastPubTime = blogSource.lastPubDate.getTime();
			obj.totalBlogs = blogSource.totalBlogs;
			obj.newBlogs = blogSource.newBlogs;
			obj.labelId = blogSource.labelId;
			obj.blogSourceId = blogSource.blogSourceId;			
            return update(UPDATE_BLOG_SOURCE, obj);
		}
		
		public function updateBlogSourceList(blogSource:Vector.<BlogSourceVO>):void
		{
			this.connection.begin();
			for each(var bs:BlogSourceVO in blogSource)
			{
				updateBlogSource(bs);
			}
			try
			{
				if(!this.connection.inTransaction)
				{
					this.connection.commit();
				}
				else
				{
					setTimeout(callLaterCommit, delayCommitInterval);
				}	
			}
			catch(e:Error)
			{
				trace(e);
			}
		}
		
		public function updateBlogSourcesLabel(blogSources:Vector.<BlogSourceVO>, labelid:int):void
		{
            this.connection.begin();
            
            for each(var bs:BlogSourceVO in blogSources)
            {
            	executeTransaction(UPDATE_BLOG_SOURCE_LABEL, {blogSourceId: bs.blogSourceId, labelId:labelid});
            }
            
            try
            {
            	this.connection.commit();
            }
            catch(e:Error)
            {
            	trace(e);
            }
		}
		
		
		public function resetBlogSourceLabel(labelid:int):Boolean
		{
			 return update(UPDATE_BLOG_SOURCE_RESET, {labelId: labelid});
		}
		
		public function resetBlogSourceLabels(labels:Vector.<BlogLabelVO>):void
		{
			this.connection.begin();
            
            for each(var bl:BlogLabelVO in labels)
            {
            	executeTransaction(UPDATE_BLOG_SOURCE_RESET, {labelId: bl.labelid});
            }
            
            try
            {
            	this.connection.commit();
            }
            catch(e:Error)
            {
            	trace(e);
            }
		}
		
		//----------------------------------------------------------------------------
		//
		// DELETE
		//
		//----------------------------------------------------------------------------
		
		public function deleteBlogSource(blogSource:BlogSourceVO):Boolean
		{
            return drop(DELETE_BLOG_SOURCE, {blogSourceId: blogSource.blogSourceId});
		}
		
		public function deleteBlogSourceByUser(user:UserVO):Boolean
		{
            return drop(DELETE_BLOG_SOURCE_BY_USER, {userId: user.userId});
		}
		
		public function deleteBlogSources(blogSources:Vector.<BlogSourceVO>):void
		{
            this.connection.begin();
            
            for each(var bs:BlogSourceVO in blogSources)
            {
            	executeTransaction(DELETE_BLOG_SOURCE, {blogSourceId: bs.blogSourceId});
            }
            
            try
            {
            	this.connection.commit();
            }
            catch(e:Error)
            {
            	trace(e);
            }
		}
		
		//----------------------------------------------------------------------------
		//
		// SELETE
		//
		//----------------------------------------------------------------------------
		
		public function selectBlogSource(blogsourceId:int):BlogSourceVO
		{
			return select(SELECT_BLOG_SOURCE, {blogSourceId: blogsourceId})[0];
		}
		
		public function selectAllBlogSource(user:UserVO):Vector.<BlogSourceVO>
		{
			return select(SELECT_ALL_BLOG_SOURCE, {userId: user.userId});
		}
		
		private function select(query:String, data:Object):Vector.<BlogSourceVO>
		{
			var result:SQLResult = execute(query, data);
			if(!result || !result.data)
			{
				return null;
			}
			
			var dataArray:Vector.<BlogSourceVO> = new Vector.<BlogSourceVO>();
						
			for each(var obj:Object in result.data)
			{
				var blogSource:BlogSourceVO = new BlogSourceVO();
				blogSource.blogSourceId = obj.blogSourceId;
				blogSource.blogLink = obj.blogLink;
				blogSource.blogName = obj.blogName;
				blogSource.blogRSS = obj.blogRSS;
				blogSource.labelId = obj.labelId;
				blogSource.lastPubDate = obj.lastPubDate;
				blogSource.newBlogs = obj.newBlogs;
				blogSource.totalBlogs = obj.totalBlogs;
				
				dataArray.push(blogSource);
			}
            return dataArray;
		}
		
		//----------------------------------------------------------------------------
		//
		// COUNT
		//
		//----------------------------------------------------------------------------
		
		public function getCount(user:UserVO):uint
		{
			return count(SELECT_COUNT, {userId: user.userId});
		}
		
	}
}